#include <iostream>
#include <algorithm>
#include <vector>

using namespace std;

const int maxn = 400;
vector<vector<int> > graph;//directed edge from vector<...> -> vector<int>
int linked[maxn];
bool visited[maxn];
int n;

void add_edge(int x, int y)
{
	graph[x].push_back(y);
}

bool hungarian_dfs(int u)
{
	typedef vector<int>::iterator iter_edge;
	for (iter_edge it = graph[u].begin(); it != graph[u].end(); it++) {
		int v = *it;
		if (!visited[v]) {
			visited[v] = true;
			if (linked[v] == -1 || hungarian_dfs(linked[v])) {
				linked[v] = u;
				return true;
			}
		}
	}
	return false;
}

int main()
{
	ios::sync_with_stdio(false);
	while(cin >> n) {
		int node_num = n + 12*7;
		graph.clear();
		graph.resize(node_num);
		for (int i = 0; i < n; i++) {
			int t;
			cin >> t;
			for (int j = 0; j < t; j++) {
				int days, classes;
				cin >> days >> classes;
				add_edge(i, n + (days-1) * 12 + classes - 1);
			}
		}

		int bi_match = 0;
		fill(linked, linked+node_num, -1);
		for (int i = 0; i < n; i++) {
			fill(visited, visited + node_num, false);
			if (hungarian_dfs(i)) bi_match++;
		}
		cout << bi_match << endl;
	}
}

